/**
 * Class: PMath
 *
 * Purpose: Math for Processing
 *
 * Created: Jan 20, 2010 @ 4:49:46 PM
 * @author Ken Scott
 */
package org.openfantasia.util.math;

public class Math4D {

	public static double[][][][] mulNoise(double[][][][] vector, double frac) {
		double[][][][] result = copy(vector);
		for (int i = 0; i < vector.length; i++) {
			result[i] = Math3D.mulNoise(result[i], frac);
		}
		return result;
	}


	public static float[][][][] mulNoise(float[][][][] vector, float frac) {
		float[][][][] result = copy(vector);
		for (int i = 0; i < vector.length; i++) {
			result[i] = Math3D.mulNoise(result[i], frac);
		}
		return result;
	}


	public static double[][][][] addNoise(double[][][][] vector, double frac) {
		double[][][][] result = copy(vector);
		for (int i = 0; i < vector.length; i++) {
			result[i] = Math3D.addNoise(result[i], frac);
		}
		return result;
	}


	public static float[][][][] addNoise(float[][][][] vector, float frac) {
		float[][][][] result = copy(vector);
		for (int i = 0; i < vector.length; i++) {
			result[i] = Math3D.addNoise(result[i], frac);
		}
		return result;
	}


	public static double[][][][] neg(double[][][][] vector) {
		double[][][][] result = copy(vector);
		for (int i = 0; i < vector.length; i++) {
			result[i] = Math3D.neg(result[i]);
		}
		return result;
	}


	public static float[][][][] neg(float[][][][] vector) {
		float[][][][] result = copy(vector);
		for (int i = 0; i < vector.length; i++) {
			result[i] = Math3D.neg(result[i]);
		}
		return result;
	}


	public static double[][][][] abs(double[][][][] vector) {
		double[][][][] result = copy(vector);
		for (int i = 0; i < vector.length; i++) {
			result[i] = Math3D.abs(result[i]);
		}
		return result;
	}


	public static float[][][][] abs(float[][][][] vector) {
		float[][][][] result = copy(vector);
		for (int i = 0; i < vector.length; i++) {
			result[i] = Math3D.abs(result[i]);
		}
		return result;
	}


	public static double[][][][] scale(double scale, double[][][][] vector) {
		double[][][][] result = copy(vector);
		for (int i = 0; i < vector.length; i++) {
			Math3D.scale(scale, result[i]);
		}
		return result;
	}


	public static float[][][][] scale(float scale, float[][][][] vector) {
		float[][][][] result = copy(vector);
		for (int i = 0; i < vector.length; i++) {
			Math3D.scale(scale, result[i]);
		}
		return result;
	}


	public static double sum(double[][][][] matrix) {
		double result = 0.0f;
		for (int x = 0; x < matrix.length; x++) {
			result += Math3D.sum(matrix[x]);
		}
		return result;
	}


	public static float sum(float[][][][] matrix) {
		float result = 0.0f;
		for (int x = 0; x < matrix.length; x++) {
			result += Math3D.sum(matrix[x]);
		}
		return result;
	}


	public static double avg(double[][][][] src) {
		double result = 0f;
		for (int i = 0; i < src.length; i++) {
			result += Math3D.avg(src[i]);
		}
		return result / (double) src.length;
	}


	public static float avg(float[][][][] src) {
		float result = 0f;
		for (int i = 0; i < src.length; i++) {
			result += Math3D.avg(src[i]);
		}
		return result / (float) src.length;
	}


	public static double max(double[][][][] matrix) {
		double result = 0.0f;
		for (int i = 0; i < matrix.length; i++) {
			double f = Math3D.max(matrix[i]);
			if (f > result) {
				result = f;
			}
		}
		return result;
	}


	public static float max(float[][][][] matrix) {
		float result = 0.0f;
		for (int i = 0; i < matrix.length; i++) {
			float f = Math3D.max(matrix[i]);
			if (f > result) {
				result = f;
			}
		}
		return result;
	}


	public static double[][][][] add(double[][][][] a, double[][][][] b) {
		double[][][][] result = empty(a);
		for (int i = 0; i < a.length; i++) {
			result[i] = Math3D.add(a[i], b[i]);
		}
		return result;
	}


	public static float[][][][] add(float[][][][] a, float[][][][] b) {
		float[][][][] result = empty(a);
		for (int i = 0; i < a.length; i++) {
			result[i] = Math3D.add(a[i], b[i]);
		}
		return result;
	}


	public static double[][][][] sub(double[][][][] a, double[][][][] b) {
		double[][][][] result = empty(a);
		for (int i = 0; i < a.length; i++) {
			result[i] = Math3D.sub(a[i], b[i]);
		}
		return result;
	}


	public static float[][][][] sub(float[][][][] a, float[][][][] b) {
		float[][][][] result = empty(a);
		for (int i = 0; i < a.length; i++) {
			result[i] = Math3D.sub(a[i], b[i]);
		}
		return result;
	}


	public static double[][][][] mul(double[][][][] a, double[][][][] b) {
		double[][][][] result = empty(a);
		for (int i = 0; i < a.length; i++) {
			result[i] = Math3D.mul(a[i], b[i]);
		}
		return result;
	}


	public static float[][][][] mul(float[][][][] a, float[][][][] b) {
		float[][][][] result = empty(a);
		for (int i = 0; i < a.length; i++) {
			result[i] = Math3D.mul(a[i], b[i]);
		}
		return result;
	}


	public static double[][][][] div(double[][][][] a, double[][][][] b) {
		double[][][][] result = empty(a);
		for (int i = 0; i < a.length; i++) {
			result[i] = Math3D.div(a[i], b[i]);
		}
		return result;
	}


	public static float[][][][] div(float[][][][] a, float[][][][] b) {
		float[][][][] result = empty(a);
		for (int i = 0; i < a.length; i++) {
			result[i] = Math3D.div(a[i], b[i]);
		}
		return result;
	}


	public static double[][][][] empty(double[][][][] a) {
		return new double[a.length][a[0].length][a[0][0].length][a[0][0][0].length];
	}


	public static float[][][][] empty(float[][][][] a) {
		return new float[a.length][a[0].length][a[0][0].length][a[0][0][0].length];
	}


	public static double[][][][] copy(double[][][][] a) {
		double[][][][] result = empty(a);

		for (int x = 0; x < a.length; x++) {
			result[x] = Math3D.copy(a[x]);
		}

		return result;
	}


	public static float[][][][] copy(float[][][][] a) {
		float[][][][] result = empty(a);

		for (int x = 0; x < a.length; x++) {
			result[x] = Math3D.copy(a[x]);
		}

		return result;
	}


	public static double[][][][] copyFill(double[][][][] a, double value) {
		double[][][][] result = empty(a);

		for (int w = 0; w < a.length; w++) {
			for (int x = 0; x < a[0].length; x++) {
				for (int y = 0; y < a[0][0].length; y++) {
					for (int z = 0; z < a[0][0][0].length; z++) {
						result[w][x][y][z] = value;
					}
				}
			}
		}

		return result;
	}


	public static float[][][][] copyFill(float[][][][] a, float value) {
		float[][][][] result = empty(a);

		for (int w = 0; w < a.length; w++) {
			for (int x = 0; x < a[0].length; x++) {
				for (int y = 0; y < a[0][0].length; y++) {
					for (int z = 0; z < a[0][0][0].length; z++) {
						result[w][x][y][z] = value;
					}
				}
			}
		}

		return result;
	}


	public static double[][][][] fill(double[][][][] a, double value) {
		for (int x = 0; x < a.length; x++) {
			Math3D.fill(a[x], value);
		}

		return a;
	}


	public static float[][][][] fill(float[][][][] a, float value) {
		for (int x = 0; x < a.length; x++) {
			Math3D.fill(a[x], value);
		}

		return a;
	}
}